﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Passwords.Models;
using System.Windows.Input;
using Passwords.DAL;

namespace Passwords.Utils
{
    internal class DemoDataUtil
    {
        private DataContext context;
        private List<CategoryContract> categories;
        private List<PasswordContract> passwords;
        private Random random = new Random(15);

        public DemoDataUtil(DataContext context)
            : base()
        {
            this.context = context;
        }

        public void CreateDemoData()
        {
            if (!context.ReadCategoryIds().Any())
            {
                CreateCategories();
                CreatePasswords();
                SaveCategories();
                SavePasswords();
            }

        }

        private void SavePasswords()
        {
            foreach (PasswordContract p in passwords)
            {
                context.SavePassword(p);
            }
        }

        private void SaveCategories()
        {
            foreach (CategoryContract c in categories)
            {
                context.SaveCategory(c);
            }
        }

        private void CreatePasswords()
        {
            passwords = new List<PasswordContract>();
            string[] names = { "Live", "Visa", "Microsoft", "MSDN", "Codeplex", "Codeproject", "PC", "Office PC", "Server", "Amazon", "Ebay","cnet","zdnet","engadget","American Express","credit card","cell phone", "App Hub", "You Tube", "Twitter", "Facebook", "My space","Workstation","Laptop" };
            int ctr=0;
            foreach (string s in names)
            {
                CreatePassword(ctr++, s);
            }
            //for (int i = 1; i < 50; i++)
            //{
            //    string s = Convert.ToChar((int)'A' + (i % 26)) + "item " + i.ToString();
            //    CreatePassword(ctr++, s);
            //}
        }

        private void CreatePassword(int ctr, string s)
        {
            int tempId = random.Next(7) + 1;
            PasswordContract pw = new PasswordContract { Guid = Guid.NewGuid(), TemplateId = tempId.ToString(), Modified = DateTime.Now, Name = s };
            pw.CategoryIds = CreatePasswordCategories(pw).ToArray();
            FillCategories(pw);
            pw.IsFavorite = ctr < 4;
            var fields = CreateFields(pw.Name).Where(f => !string.IsNullOrEmpty(f.Value)).ToArray();
            foreach (var f in fields)
            {
                pw.Fields.Add(f);
            }
            //if (pw.Name == "Amazon")
            //{
            //    pw.Fields.Add(new FieldContract { Name = "custom", Value = "custom value", Id = "custom1" });
            //}
            passwords.Add(pw);
        }

        private void FillCategories(PasswordContract pw)
        {
            var col = pw.Categories;
            foreach (string id in pw.CategoryIds)
            {
                CategoryContract c = categories.FirstOrDefault(cat => cat.Id == id);
                if (c != null) col.Add(c);
            }
        }

        private List<string> CreatePasswordCategories(PasswordContract pw)
        {
            List<string> list = new List<string>();
            HashSet<string> hash=new HashSet<string>();
            Random r = random;
            int max = r.Next(12);

            int n = categories.Count;
            for (int i = 0; i < max; i++)
            {
                int index = r.Next(n);
                string s = categories[index].Id;
                if (!hash.Contains(s))
                {
                    hash.Add(s);
                    list.Add(s);
                }
            }
            return list;
        }

        private void CreateCategories()
        {
            categories = new List<CategoryContract>();
            string[] names = { "Banking", "Computer", "Internet", "Home", "Office", "Private", "Public", "EMails", "Other" };
            int id=1;
            foreach (string s in names)
            {
                CategoryContract c = new CategoryContract { Modified = DateTime.Now, Name = s, Id=id.ToString() };
                id++;
                if (s != "Public")
                {
                    int max = s == "Other" ? 1 : 1000;
                    c.TransferFields = CreateEmptyFields(c.Name,max);
                }
                categories.Add(c);
            }
        }

        private static FieldContract[] CreateEmptyFields(string name, int max)
        {
            var fields = CreateFields(name);
            while (fields.Count > max)
            {
                fields.RemoveAt(0);
            }
            foreach (var f in fields) f.Value = null;
            return fields.ToArray();
        }

        private static List<FieldContract> CreateFields(string name)
        {
            List<FieldContract> fields = new List<FieldContract>();
            fields.Add(new FieldContract { Id = "a", Name = "Password", Value = "p@ssw0rd", InputScope = PhoneInputScopeNameValue.Password });
            fields.Add(new FieldContract { Id = "b", Name = "user name", Value = name, InputScope = PhoneInputScopeNameValue.Email });
            fields.Add(new FieldContract { Id = "c", Name = "email ", Value = name + "@live.com", InputScope = PhoneInputScopeNameValue.Email });
            fields.Add(new FieldContract { Id = "d", Name = "url ", Value = "http://www.social.msdn.microsoft.com/" + name, InputScope = PhoneInputScopeNameValue.Url });
            fields.Add(new FieldContract { Id = "e", Name = "Info ", Value = "", InputScope = PhoneInputScopeNameValue.Default });
            fields.Add(new FieldContract { Id = "f", Name = "Pin", Value = "5410", InputScope = PhoneInputScopeNameValue.Number }); return fields;
        }

        public static void ResetDb()
        {
            using (DataContext context = new DataContext())
            {
                context.DeleteDatabase();
            }
            using (DataContext context = new DataContext())
            {
                context.ChangePassword("", "password");
                if (context.Login("password"))
                {
                    new DemoDataUtil(context).CreateDemoData();
                    context.Logout();
                }
            }
        }
    }
}
